package com.system.vote.admin.controller;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.system.vote.common.utils.StringUtils;
import com.system.vote.core.customBean.PageBean;
import com.system.vote.core.http.Result;
import com.system.vote.admin.entity.SysAccount;
import com.system.vote.admin.entity.SysRole;
import com.system.vote.admin.entity.SysUserRole;
import com.system.vote.admin.service.SysAccountService;
import com.system.vote.admin.service.SysRoleService;
import com.system.vote.admin.service.SysUserRoleService;
import io.swagger.annotations.Api;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 */
@RestController
@RequestMapping("/sys/user")
@Api(tags = "PC后台系统用户")
public class SysAccoutController {
    @Autowired
    private SysAccountService sysAccountService;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Value("${avatarImageFilePath}")
    private String avatarImageFilePath;

    @Value("${originPwd}")
    private String originPwd;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @PostMapping("/save")
    @PreAuthorize("hasAuthority('system:user:add')" + "||" + "hasAuthority('system:user:edit')" + "||" + "hasAuthority('system:user:updateBaseInfo')")
    public Result saveUser(@RequestBody SysAccount sysAccount) {
        if (sysAccount.getId() < 0) {
            Date d = new Date();
            sysAccount.setCreateTime(d);
            sysAccount.setUpdateTime(d);
            sysAccount.setPassword(bCryptPasswordEncoder.encode(sysAccount.getPassword()));
            sysAccountService.save(sysAccount);
            //新创建的用户分配普通用户角色
            SysUserRole sysUserRole=new SysUserRole();
            sysUserRole.setUserId(sysAccount.getId());
            sysUserRole.setRoleId(2L);
            sysUserRoleService.save(sysUserRole);
        } else {
            sysAccount.setUpdateTime(new Date());
            sysAccountService.updateById(sysAccount);
        }
        return Result.success(sysAccount);
    }

    @PostMapping("/updateUserPwd")
    @PreAuthorize("hasAuthority('system:user:updateBaseInfo')")
//    @AutoLog("修改用户密码")
    public Result updateUserPwd(@RequestBody SysAccount sysAccount) {
        SysAccount currentUser = sysAccountService.getById(sysAccount.getId());
        if (bCryptPasswordEncoder.matches(sysAccount.getOldPassword(), currentUser.getPassword())) {
            String newPassWord = bCryptPasswordEncoder.encode(sysAccount.getNewPassword());
            currentUser.setPassword(newPassWord);
            currentUser.setUpdateTime(new Date());
            if (sysAccountService.updateById(currentUser)) {
                return Result.success("密码修改成功,下次登录生效", currentUser);
            } else {
                return Result.error(500, "密码修改失败");
            }
        } else {
            return Result.error(500, "原密码错误");
        }
    }

    @PostMapping("/uploadImage")
    @PreAuthorize("hasAuthority('system:user:uploadUserAvatar')")
//    @AutoLog("上传用户头像")
    public Result uploadImage(MultipartFile file) throws Exception {
        Map<String, Object> dataMap = new HashMap<>();
        if (!file.isEmpty()) {
            String originalFileName = file.getOriginalFilename();
            String suffixName = null;
            if (originalFileName != null) {
                suffixName = originalFileName.substring(originalFileName.lastIndexOf("."));
            }
            String newFileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + "_" + UUID.randomUUID().toString() + suffixName;
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File(avatarImageFilePath + newFileName));
            dataMap.put("fileName", newFileName);
            dataMap.put("src", "image/userAvatar/" + newFileName);
        }
        return Result.success("上传成功", dataMap);
    }

    @PostMapping("/updateAvatar")
    @PreAuthorize("hasAuthority('system:user:updateBaseInfo')")
//    @AutoLog("更新用户头像")
    public Result updateAvatar(@RequestBody SysAccount sysAccount) {
        SysAccount currentUser = sysAccountService.getById(sysAccount.getId());
        currentUser.setUpdateTime(new Date());
        currentUser.setAvatar(sysAccount.getAvatar());
        sysAccountService.updateById(sysAccount);
        return Result.success("更新头像成功", sysAccount);
    }

    @PostMapping("/list")
    @PreAuthorize("hasAuthority('system:user:list')")
    public Result list(@RequestBody PageBean pageBean) {
        String query = pageBean.getQuery().trim();

        Page<SysAccount> pageResult = sysAccountService.page(
                new Page<>(pageBean.getPageNum(),
                        pageBean.getPageSize()),
                new QueryWrapper<SysAccount>()
                        .select("id", "avatar", "username", "email", "phone", "status", "update_time,create_time")
                        .like(StringUtils.isNotEmpty(query), "username", query)
                        .ne("is_delete", "1")
                        .orderByDesc("update_time"));
        List<SysAccount> userList = pageResult.getRecords();
        for (SysAccount sysAccount : userList) {
            List<SysRole> roleList = sysRoleService.list(new QueryWrapper<SysRole>().inSql("id", "select role_id from sys_user_role where user_id= " + sysAccount.getId()));
            sysAccount.setSysRoleList(roleList);
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("userList", userList);
        resultMap.put("total", pageResult.getTotal());

        return Result.success(resultMap);
    }

//    @PostMapping("/export")
//    @PreAuthorize("hasAuthority('system:user:downfile')")
//    public void downFile(@RequestBody PageBean pageBean, HttpServletResponse res) {
//        File file = sysUserService.createUserExcelFile(pageBean);
//        CommonFileUtils.downloadFile(res, file, file.getName());
//    }

    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('system:user:query')")
//    @AutoLog("查询用户信息")
    public Result findById(@PathVariable Integer id) {
        SysAccount sysAccount = sysAccountService.getById(id);
        Map<String, Object> map = new HashMap<>();
        map.put("sysUser", sysAccount);
        return Result.success(map);
    }

    @PostMapping("/checkUserName")
    @PreAuthorize("hasAuthority('system:user:query')")
    public Result checkUserName(@RequestBody SysAccount sysAccount) {
        if (sysAccountService.getByUserName(sysAccount.getUsername()) == null) {
            return Result.success();
        } else {
            return Result.error();
        }
    }
    @PostMapping("/checkPhone")
    @PreAuthorize("hasAuthority('system:user:query')")
    public Result checkPhone(@RequestBody SysAccount sysAccount) {
        if (sysAccountService.getByPhone(sysAccount.getPhone()) == null) {
            return Result.success();
        } else {
            return Result.error();
        }
    }
    @PostMapping("/checkEmail")
    @PreAuthorize("hasAuthority('system:user:query')")
    public Result checkEmail(@RequestBody SysAccount sysAccount) {
        if (sysAccountService.getByEmail(sysAccount.getEmail()) == null) {
            return Result.success();
        } else {
            return Result.error();
        }
    }
    /**
     * @param ids
     * @return
     */
    @Transactional
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('system:user:delete')")
//    @AutoLog("删除用户信息")
    public Result delete(@RequestBody List<SysAccount> sysAccountList) {
//        List<Long> idList = Arrays.stream(ids).boxed().collect(Collectors.toList());
        //超级管理员不能删除
        sysAccountList.removeIf(n -> n.getId() == 1);
        sysAccountList.forEach(t -> {
            t.setIsDelete("1");
        });
        System.out.println("sysUserList:" + sysAccountList);
        sysAccountService.saveOrUpdateBatch(sysAccountList);
        System.out.println("sysUserList:" + sysAccountList);

        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id",
                sysAccountList.stream().map(SysAccount::getId)
                        .collect(Collectors.toList())));
        return Result.success();
    }

    @GetMapping("/resetPwd/{id}")
    @PreAuthorize("hasAuthority('system:user:edit')")
//    @AutoLog("初始化用户名密码")
    public Result resetPwd(@PathVariable Long id) {
        SysAccount sysAccount = sysAccountService.getById(id);
        sysAccount.setUpdateTime(new Date());
        sysAccount.setPassword(bCryptPasswordEncoder.encode(originPwd));
        sysAccountService.updateById(sysAccount);
        return Result.success("重置密码成功");
    }

    @PostMapping("/updateUserStatus")
    @PreAuthorize("hasAuthority('system:user:edit')")
//    @AutoLog("更新用户状态")
    public Result updateUserStatus(@RequestBody SysAccount sysAccount) {
        SysAccount currentAccount = sysAccountService.getById(sysAccount.getId());
        currentAccount.setUpdateTime(new Date());
        currentAccount.setStatus(sysAccount.getStatus());
        sysAccountService.updateById(currentAccount);
        return Result.success("更新用户状态成功");
    }
}
